package com.ymatou.impl;

import com.ymatou.database.model.Account;
import com.ymatou.database.wrapper.AccountWapper;
import com.ymatou.iapi.accounting.parameter.*;
import com.ymatou.iapi.accounting.service.*;
import com.ymatou.interfaces.AccountCallService;
import com.ymatou.pojo.AccountingBean;
import com.ymatou.pojo.AccountingItemBean;
import com.ymatou.utils.TestDataManager;
import com.ymatou.utils.YMTDateUtil;
import com.ymatou.utils.common.enums.AccountOperateTypeEnum;
import com.ymt.core.tool.Logger;
import org.apache.http.client.ClientProtocolException;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Service
public class AccountCallServiceV2 implements AccountCallService {

    /**
     * 获取AccountId，如果没创建一个
     *
     * @param uid UserId 默认查询 AccountType 为1的账户信息
     * @return accountId
     * @throws Exception
     */
    public String getAccountId(Long uid) throws Exception {
        String aid = null;
        try {
            Logger.comment("获取Uid" + uid + "对应的AccountId");
            // 查询Uid对应的Accountid
            GetAccountByUserIdBean getaccountbyuseridBean = new GetAccountByUserIdBean();
            GetAccountByUserIdCall getaccountbyuseridCall = new GetAccountByUserIdCall();
            getaccountbyuseridBean.setUserId(uid);
            getaccountbyuseridBean.setAccountType(1);
            getaccountbyuseridBean.setAppId("AutoTest");
            getaccountbyuseridCall.setData(false, getaccountbyuseridBean);
            getaccountbyuseridCall.callService();
            aid = getaccountbyuseridCall.getAccountId();
            Logger.comment("获取一个AccountId:" + aid);
            // 如果没获取到会出错 空指针异常，走自动创建流程
        } catch (Exception e) {
            try {
                Logger.comment("没有获取到AccountId,自动创建一个新的");
                CreateAccountBean createaccountBean = new CreateAccountBean();
                CreateAccountCall createaccountCall = new CreateAccountCall();
                createaccountBean.setAccountType(1);
                createaccountBean.setAppId("AutoTest");
                createaccountBean.setCurrencyType(1);
                createaccountBean.setMemo("自动化测试专用");
                createaccountBean.setUserId(uid);
                createaccountCall.setData(false, createaccountBean);
                createaccountCall.callService();
                Logger.comment("没有获取到AccountId，创建一个:"
                        + createaccountCall.getReturnData());
                aid = createaccountCall.getAccountId();
            } catch (Exception e1) {
                // 创建也报错时,打印错误,抛出异常
                e1.printStackTrace();
                throw e1;
            }
        }
        return aid;
    }

    /**
     * @param accountingBean
     * @throws ClientProtocolException
     * @throws IOException
     */
    public void Accounting(AccountingBean accountingBean)
            throws ClientProtocolException, IOException {
        AccountingCall accountingCall = new AccountingCall();
        accountingCall.setData(false, accountingBean);
        accountingCall.callService();
    }
    /**
     * 获取AccountId，如果没创建一个
     *
     * @param uid UserId
     * @param accountType 账户类型
     * @return accountId
     * @throws Exception
     */
    public String getAccountId(Long uid, int accountType)
            throws Exception {
        String aid = null;
        try {
            Logger.comment("获取Uid" + uid + "对应的AccountId");
            // 查询Uid对应的Accountid
            GetAccountByUserIdBean getaccountbyuseridBean = new GetAccountByUserIdBean();
            GetAccountByUserIdCall getaccountbyuseridCall = new GetAccountByUserIdCall();
            getaccountbyuseridBean.setUserId(uid);
            getaccountbyuseridBean.setAccountType(accountType);
            getaccountbyuseridBean.setAppId("AutoTest");
            getaccountbyuseridCall.setData(false, getaccountbyuseridBean);
            getaccountbyuseridCall.callService();
            aid = getaccountbyuseridCall.getAccountId();
            Logger.comment("获取一个AccountId:" + aid);

            // 如果没获取到会出错 空指针异常，走自动创建流程
        } catch (Exception e) {
            try {
                Logger.comment("没有获取到AccountId,自动创建一个新的");
                CreateAccountBean createaccountBean = new CreateAccountBean();
                CreateAccountCall createaccountCall = new CreateAccountCall();
                createaccountBean.setAccountType(accountType);
                createaccountBean.setAppId("AutoTest");
                createaccountBean.setCurrencyType(1);
                createaccountBean.setMemo("自动化测试专用");
                createaccountBean.setUserId(uid);
                createaccountCall.setData(false, createaccountBean);
                createaccountCall.callService();
                Logger.comment("没有获取到AccountId，创建一个:"
                        + createaccountCall.getReturnData());
                aid = createaccountCall.getAccountId();
            } catch (Exception e1) {
                // 创建也报错时,打印错误,抛出异常
                e1.printStackTrace();
                throw e1;
            }
        }
        return aid;
    }

    /**
     * 获取没有AccountId的uid，尝试5次<br>
     * 如果一次都没获取到 返回0
     *
     * @return newUid
     * @throws Exception
     */
    public static int getNewUid() throws Exception {
        int nuid = 0;
        try {
            for (int i = 0; i < 5; i++) {
                nuid = 99000000 + Integer.valueOf(TestDataManager
                        .getRandomNum(6));
                List<Account> list = new AccountWapper()
                        .selectAccountInfoByUserId(nuid);
                Logger.debug("Account info:" + list);
                if (list.size() <= 0) {
                    return nuid;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Logger.comment("获取一个AccountInfo表中没有的新UserId:" + nuid);
        return 0;
    }

    /**
     * 锁定accountId
     *
     * @param accountId
     */
    public void lockAccountId(String accountId) {
        try {
            Logger.comment("锁定账户:" + accountId);
            SetAccountLockStatusBean setaccountlockstatusBean = new SetAccountLockStatusBean();
            SetAccountLockStatusCall setaccountlockstatusCall = new SetAccountLockStatusCall();
            setaccountlockstatusBean.setAccountId(accountId);
            setaccountlockstatusBean.setStatus(1);
            setaccountlockstatusBean.setAppId("AutoTest");
            setaccountlockstatusBean.setMemo("自动化测试Lock");
            setaccountlockstatusCall.setData(false, setaccountlockstatusBean);
            setaccountlockstatusCall.callService();

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 解锁accountId
     *
     * @param accountId
     */
    public void unlockAccountId(String accountId) {
        try {
            Logger.comment("解锁账户:" + accountId);
            SetAccountLockStatusBean setaccountlockstatusBean = new SetAccountLockStatusBean();
            SetAccountLockStatusCall setaccountlockstatusCall = new SetAccountLockStatusCall();
            setaccountlockstatusBean.setAccountId(accountId);
            setaccountlockstatusBean.setStatus(0);
            setaccountlockstatusBean.setAppId("AutoTest");
            setaccountlockstatusBean.setMemo("自动化测试UnLock");
            setaccountlockstatusCall.setData(false, setaccountlockstatusBean);
            setaccountlockstatusCall.callService();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取Fundin 信息
     *
     * @param accountId 账户ID
     * @param amount 发生金额
     * @param bizCode 业务编码
     * @param originalNo 原始单据号
     * @return AccountingItemBean
     * @throws InterruptedException
     */
    public AccountingItemBean getFundinBean(String accountId,
                                                   BigDecimal amount, int bizCode, String originalNo)
            throws InterruptedException {
        if (accountId != null && originalNo != null) {
            Logger.comment(accountId + "账号余额增加" + amount + ",原始单据:"
                    + originalNo);
        }
        AccountingItemBean aib = new AccountingItemBean();
        aib.setAccountId(accountId);
        aib.setAccountingDate(YMTDateUtil
                .getSysTime("yyyy-MM-dd HH:mm:ss.SSSSSS"));
        aib.setAccountOperateType(AccountOperateTypeEnum.Fundin.getValue());
        aib.setAmount(amount);
        aib.setBizCode(bizCode);
        aib.setBizNo(TestDataManager.getRandomUUID().toString());
        aib.setCurrencyType(1);
        aib.setMemo("自动化测试:" + AccountOperateTypeEnum.Fundin);
        aib.setOperator("AutoTestOperator");
        aib.setOriginalNo(originalNo);
        return aib;

    }

    /**
     * 获取Fundout 信息
     *
     * @param accountId 账户ID
     * @param amount 发生金额
     * @param bizCode 业务编码
     * @param originalNo 原始单据号
     * @return AccountingItemBean
     * @throws InterruptedException
     */
    public AccountingItemBean getFundoutBean(String accountId,
                                                    BigDecimal amount, int bizCode, String originalNo)
            throws InterruptedException {
        Logger.comment(accountId + "账号余额减少" + amount + ",原始单据:" + originalNo);
        AccountingItemBean aib = new AccountingItemBean();
        aib.setAccountId(accountId);
        aib.setAccountingDate(YMTDateUtil
                .getSysTime("yyyy-MM-dd HH:mm:ss.SSSSSS"));
        aib.setAccountOperateType(AccountOperateTypeEnum.Fundout.getValue());
        aib.setAmount(amount);
        aib.setBizCode(bizCode);
        aib.setBizNo(TestDataManager.getRandomUUID().toString());
        aib.setCurrencyType(1);
        aib.setMemo("自动化测试:" + AccountOperateTypeEnum.Fundout);
        aib.setOperator("AutoTestOperator");
        aib.setOriginalNo(originalNo);
        return aib;

    }

    /**
     * 获取Freeze 信息
     *
     * @param accountId 账户ID
     * @param amount 发生金额
     * @param bizCode 业务编码
     * @param originalNo 原始单据号
     * @return AccountingItemBean
     * @throws InterruptedException
     */
    public AccountingItemBean getFreezeBean(String accountId,
                                                   BigDecimal amount, int bizCode, String originalNo)
            throws InterruptedException {
        Logger.comment(accountId + "账号冻结增加" + amount + ",原始单据:" + originalNo);
        AccountingItemBean aib = new AccountingItemBean();
        aib.setAccountId(accountId);
        aib.setAccountingDate(YMTDateUtil
                .getSysTime("yyyy-MM-dd HH:mm:ss.SSSSSS"));
        aib.setAccountOperateType(AccountOperateTypeEnum.Freeze.getValue());
        aib.setAmount(amount);
        aib.setBizCode(bizCode);
        aib.setBizNo(TestDataManager.getRandomUUID().toString());
        aib.setCurrencyType(1);
        aib.setMemo("自动化测试:" + AccountOperateTypeEnum.Freeze);
        aib.setOperator("AutoTestOperator");
        aib.setOriginalNo(originalNo);
        return aib;

    }

    /**
     * 获取Freeze 信息
     *
     * @param accountId 账户ID
     * @param amount 发生金额
     * @param bizCode 业务编码
     * @param originalNo 原始单据号
     * @return AccountingItemBean
     * @throws InterruptedException
     */
    public AccountingItemBean getUnfreezeBean(String accountId,
                                                     BigDecimal amount, int bizCode, String originalNo)
            throws InterruptedException {
        Logger.comment(accountId + "账号冻结减少" + amount + ",原始单据:" + originalNo);
        AccountingItemBean aib = new AccountingItemBean();
        aib.setAccountId(accountId);
        aib.setAccountingDate(YMTDateUtil
                .getSysTime("yyyy-MM-dd HH:mm:ss.SSSSSS"));
        aib.setAccountOperateType(AccountOperateTypeEnum.Unfreeze.getValue());
        aib.setAmount(amount);
        aib.setBizCode(bizCode);
        aib.setBizNo(TestDataManager.getRandomUUID().toString());
        aib.setCurrencyType(1);
        aib.setMemo("自动化测试:" + AccountOperateTypeEnum.Unfreeze);
        aib.setOperator("AutoTestOperator");
        aib.setOriginalNo(originalNo);
        return aib;
    }

    /**
     * 初始化账户，解锁后设置余额
     *
     * @param accountid1 账户id
     * @param newAmount 余额
     * @param newFreeze 冻结金额
     * @return
     */
    public AccountingBean resetAccount(String accountid1,
                                              BigDecimal newAmount, BigDecimal newFreeze) {
        try {
            unlockAccountId(accountid1);
            Logger.comment("初始化账户：" + accountid1 + " 余额:" + newAmount + "冻结:"
                    + newFreeze);
            Account m = new AccountWapper().selectAccountInfo(accountid1)
                    .get(0);
            BigDecimal amount = m.getAvailAmount();
            BigDecimal freezeamount = m.getFreezeAmount();
            AccountingBean accountingBean = new AccountingBean();
            AccountingCall accountingCall = new AccountingCall();
            accountingBean.setAppId("AutoTest");
            List<AccountingItemBean> AccountingItems = new ArrayList<AccountingItemBean>();
            String oNo = TestDataManager.getRandomUUID().toString();
            if (amount.floatValue() > 0) {
                AccountingItems.add(this.getFundoutBean(
                        accountid1, amount, 100001, oNo));
            }
            if (freezeamount.floatValue() > 0) {
                AccountingItems.add(this.getUnfreezeBean(
                        accountid1, freezeamount, 100001, oNo));
            }
            if (newAmount.floatValue() > 0) {
                AccountingItems.add(this.getFundinBean(
                        accountid1, newAmount, 100001, oNo));
            }
            if (newFreeze.floatValue() > 0) {
                AccountingItems.add(this.getFreezeBean(
                        accountid1, newFreeze, 100001, oNo));
            }
            accountingBean.setAccountingItems(AccountingItems);
            accountingCall.setData(false, accountingBean);
            accountingCall.callService();
            return accountingBean;
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 根据userId，账户类型	查询用户余额
     * @param userId
     * @param accountType
     * @return	availAmount
     */
    public BigDecimal getAccountBalance(int userId, int accountType) {

        BigDecimal availAmount = BigDecimal.ZERO;

        GetAccountBalanceBean getaccountbalanceBean = new GetAccountBalanceBean();
        GetAccountBalanceCall getaccountbalanceCall = new GetAccountBalanceCall();

        getaccountbalanceBean.setUserId(userId);
        getaccountbalanceBean.setAccountType(accountType);
        getaccountbalanceBean.setAppId("AutoTest");
        getaccountbalanceCall.setData(false, getaccountbalanceBean);

        try {

            getaccountbalanceCall.callService();

            availAmount = new BigDecimal(getaccountbalanceCall.getAvailAmount());

        } catch (Exception e) {
            Logger.info(String.format("##########查询用户:%s,账户类型:%s 账户余额失败",
                    userId, accountType));
        }

        return availAmount;

    }
    /**
     * 根据userId，查询用户资金流水 默认查询返回最近的4笔资金流水
     * @param userId
     * @return
     */
    public List<AccountEntryBean> getAccountentrylist(Long userId) {

        GetAccountEntryListBean getaccountentrylistBean = new GetAccountEntryListBean();
        GetAccountEntryListCall getaccountentrylistCall = new GetAccountEntryListCall();

        int pageIndex = 1;
        int pageSize = 10;

        List<AccountEntryBean> accountEntryList = new ArrayList<AccountEntryBean>();

        try {

            String accountid = this.getAccountId(userId);

            getaccountentrylistBean.setAccountId(accountid);
            getaccountentrylistBean.setAppId("AutoTest");
            getaccountentrylistBean.setPageIndex(pageIndex);
            getaccountentrylistBean.setPageSize(pageSize);
            getaccountentrylistCall.setData(false, getaccountentrylistBean);

            getaccountentrylistCall.callService();

            accountEntryList = getaccountentrylistCall.getReturnAccountList();

        } catch (Exception e) {

            Logger.info(String.format("##########查询用户:%s 账户资金流水失败", userId));
        }

        return accountEntryList;

    }
    public static void main(String[] args) throws Exception {
        AccountCallServiceV2 accountCallService = new AccountCallServiceV2();

        String accountId = accountCallService.getAccountId(1234L);

        accountCallService.resetAccount(accountId, new BigDecimal("9000000"), BigDecimal.ZERO);

        System.out.println(accountId);
    }
}
